package org.wxd.account.engine.user;

import org.wxd.account.api.user.UserService;
import org.wxd.account.api.user.dto.*;
import org.wxd.account.api.user.exception.EmailExistsException;
import org.wxd.account.api.user.exception.UserNotFoundException;
import org.wxd.account.domain.user.User;
import org.wxd.account.domain.user.UserMoreInfo;
import org.wxd.account.domain.user.UserOperations;
import org.wxd.common.utils.Assert;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.Optional;

/**
 * Created by wangxd on 2015/10/30.
 */
@Transactional
public class UserServiceImpl implements UserService{

    @Resource
    private UserOperations uOps;


    private User buildUser(UserAddRequest request,UserMoreInfo.Type type){
        Assert.notNull(request, "request must not be null.");
        if(uOps.ofEmail(request.email()).isPresent()) throw new EmailExistsException();
        return User.newBuilder()
                .email(request.email())
                .password(request.password())
                .moreInfo(UserMoreInfo.newBuilder()
                        .name(request.name())
                        .type(type)
                        .build())
                .build();
    }


    public UserRecord addAdmin(UserAddRequest request) {
        User user = buildUser(request, UserMoreInfo.Type.ADMIN);
        uOps.store(user);
        return UserHelper.asUserRecord(user);
    }

    public UserRecord addSeller(UserAddRequest request) {
        User user = buildUser(request, UserMoreInfo.Type.SELLER);
        uOps.store(user);
        return UserHelper.asUserRecord(user);
    }

    public UserRecord addPurchaser(UserAddRequest request) {
        User user = buildUser(request, UserMoreInfo.Type.PURCHASER);
        uOps.store(user);
        return UserHelper.asUserRecord(user);
    }

    public UserRecord active(UserActiveRequest request) {
        Assert.notNull(request, "request must not be null.");
        Optional<User> userOpt = uOps.ofId(request.userId());
        if(!userOpt.isPresent()) throw new UserNotFoundException();
        User user = userOpt.get();
        user.active();
        uOps.store(user);
        return UserHelper.asUserRecord(user);
    }

    public UserRecord remove(UserRemoveRequest request) {
        Assert.notNull(request,"request must not be null.");
        Optional<User> userOpt = uOps.ofId(request.userId());
        if(!userOpt.isPresent())  throw new UserNotFoundException();
        User user = userOpt.get();
        uOps.store(user.lock());
        return UserHelper.asUserRecord(user);
    }

    public UserRecord reset(UserResetRequest request) {
        Assert.notNull(request,"request must not be null.");
        Optional<User> userOpt = uOps.ofId(request.userId());
        if(!userOpt.isPresent()) throw new UserNotFoundException();
        User user = userOpt.get();
        user.updateModifyTime().email(request.email()).moreInfo().name(request.name());
        uOps.store(user);
        return UserHelper.asUserRecord(user);
    }
}
